package org.example;

import com.alibaba.fastjson.JSON;

import java.security.PublicKey;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author liukaihao
 * @date 2025/03/03
 */
public class Main9 {
    public static void main(String[] args) {
        Book book1 = new Book("1", "程序元的自我修改1", "大卫1", "图灵出版设1");
        Book book2 = new Book("2", "程序元的自我修改2", "大卫2", "图灵出版设2");
        Book book3 = new Book("3", "程序元的自我修改3", "大卫3", "图灵出版设3");

        Book book4 = new Book("4", "程序元的自我修改4", "大卫4", "图灵出版设4");


        Book book5 = new Book("5", "程序元的自我修改5", "大卫5", "图灵出版设5");

        Book book6 = new Book("6", "程序元的自我修改6", "大卫6", "图灵出版设6");

        List<Book> books = new ArrayList<>();
        books.add(book1);
        books.add(book2);
        books.add(book3);
        books.add(book4);
        books.add(book5);
        books.add(book6);
//3.使用Set去重（10分）将图书列表转换为Set<Book>，去除重复的图书记录（假设图书的唯一标识是其标题和作者）
        Set<String> set = new HashSet<>();
        for (Book book : books) {
            String key = book.getTitle() + book.getAuthor();
            set.add(key);
        }
        System.out.println("第一题："+ JSON.toJSONString(set));
        //4.使用Map存储图书信息使用 Map<String, Book>存储图书信息，其中键为图书标题，值为Book对象
        HashMap<String, Book> map = new HashMap<>();
        for (Book book : books) {
            String key = book.getTitle();
            map.put(key,book);
        }
        //5.实现一个方法，接收一个关键词参数，返回包含该关键词的所有图书信息列表
        List<Book> list5 = test5(books,"程序员的自我修养5");

        // //6.创建线程安全的图书列表.使用线程安全的集合类（如CopyOnWriteArrayList或Collections.synchronizedList）创建一个线程安全的图书列表
        List<Book> syncList = Collections.synchronizedList(books);
        System.out.println("第6题："+JSON.toJSONString(syncList));

        //7 7.实现图书列表的并发修改（10分）
        //¢创建多个线程模拟同时向图书列表中添加新的图书记录。
        //¢确保在并发修改过程中不会出现数据不一致的问题。
        addBooks7(syncList);

        //8.¢创建多个线程模拟同时从图书列表中读取图书信息。
        //确保读取操作不会受到写入操作的影响。
        readBooks8(syncList);

        //9.¢在图书列表的增删操作中使用synchronized关键字确保线程安全。
        syncAddBooks9(syncList);


        //10.使用Lock接口进行显式锁管理（10分）
        //¢使用ReentrantLock或其他Lock实现类替代synchronized关键字，实现对图书列表的细粒度锁管理。
        lockBooks10(syncList);
    }
    //5 ¢实现一个方法，接收一个关键词参数，返回包含该关键词的所有图书信息
    public static  List<Book> test5(List<Book> books,String title) {
        ArrayList<Book> list = new ArrayList<>();
        for (Book book : books) {
            if(book.getTitle().equals(title)) {
                list.add(book);
            }
        }
        return list;
    }
    public static List<Book> addBooks7(List<Book> books) {
        ReentrantLock lock = new ReentrantLock();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    Book book7 = new Book("7", "程序员的自我修养7,", "大卫7", "图灵出版社7");
                    books.add(book7);
                } catch (Exception e) {
                    lock.unlock();
                }
            }
        });

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    Book book8 = new Book("8", "程序员的自我修养8", "大卫8", "图灵出版社8");
                    books.add(book8);
                } catch (Exception e) {
                    lock.unlock();
                }
            }
        });
        return books;
    }

    public static List<Book> readBooks8(List<Book> books) {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        // 提交多个线程
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                books.stream().forEach(book -> {
                    System.out.println(JSON.toJSONString(book));
                });
            }
        });
        executorService.shutdownNow();
        return books;
    }

    public static  synchronized  List<Book> syncAddBooks9(List<Book> books) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Book book9 = new Book("9","程序员的自我修养9","大卫9","图灵出版社9");
                books.add(book9);
            }
        });
        return books;
    }
    public static synchronized List<Book>  syncDelBooks9(List<Book> books){
        new Thread(new Runnable() {
            @Override
            public void run() {
                books.remove(1);
            }
        });
        return books;
    }
    public static  void lockBooks10(List<Book> books){
        ReentrantLock lock = new ReentrantLock();
        for(int i = 0;i<10;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    lock.lock();
                    try {
                        System.out.println(Thread.currentThread().getName());
                    }catch (Exception e){
                        lock.unlock();
                    }
                }
            });
        }
    }
}
